package com.jixiang.order.controller;



import cn.hutool.core.lang.UUID;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.api.ApiController;
import com.baomidou.mybatisplus.extension.api.R;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jixiang.apiFeignt.clients.AdrClient;
import com.jixiang.apiFeignt.clients.GoodsClient;
import com.jixiang.model.common.dtos.ResponseResult;
import com.jixiang.model.common.enums.AppHttpCodeEnum;
import com.jixiang.model.goods.dtos.CartDtos;
import com.jixiang.model.goods.entity.GsGoodsSkus;
import com.jixiang.model.order.dtos.OrderDtos;
import com.jixiang.model.order.entity.OsOrderInfo;
import com.jixiang.model.user.entity.UsUser;
import com.jixiang.order.config.RedisIdWorker;
import com.jixiang.order.service.OsOrderInfoService;
import com.jixiang.utils.thread.UserThread;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.util.concurrent.ListenableFutureCallback;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import static com.jixiang.common.constants.CodeMqConstants.*;
import static com.jixiang.common.constants.OrderConstants.ID_WORK_ORDER;
import static com.jixiang.common.constants.RedisConstants.REDIS_GOODS_ID;
import static com.jixiang.common.constants.RedisConstants.REDIS_SKU_ID;
import static com.jixiang.model.common.enums.AppHttpCodeEnum.INSUFFICIENT_INVENTORY;

/**
 * (OsOrderInfo)表控制层
 *
 * @author makejava
 * @since 2023-11-07 12:46:18
 */
@Slf4j
@RestController
@RequestMapping("order")
public class OsOrderInfoController extends ApiController {
    /**
     * 服务对象
     */
    @Resource
    private OsOrderInfoService osOrderInfoService;

    @Autowired
    GoodsClient goodsClient;

    @Autowired
    RabbitTemplate rabbitTemplate;

    private static final DefaultRedisScript<Long> SECKILL_SCRIPT;
    static {
        SECKILL_SCRIPT = new DefaultRedisScript<>();
        SECKILL_SCRIPT.setLocation(new ClassPathResource("goods.lua"));
        SECKILL_SCRIPT.setResultType(Long.class);
    }

    @Autowired
    StringRedisTemplate stringRedisTemplate;


    @ApiOperation("获取订单")
    @GetMapping("getOrder")
    public ResponseResult getOrder(@RequestParam(required = true,value = "id") String id){
       return   osOrderInfoService.getOrder(id);
    }

    @ApiOperation("获取订单列表")
    @GetMapping("getOrderList")
    public ResponseResult getOrderList(@RequestParam(required = true,value = "orderState") int orderState,
                                       @RequestParam(required = true,value = "pageSize") int pageSize,
                                       @RequestParam(required = true,value = "pageNum") int pageNum){
        return   osOrderInfoService.getOrderList(orderState,pageSize,pageNum);
    }

//    @ApiOperation("wx获取订单列表")
//    @GetMapping("wxGetOrderList")
//    public ResponseResult wxGetOrderList(@RequestParam(required = true,value = "orderState") int orderState){
//        return   osOrderInfoService.wxGetOrderList(orderState);
//    }

    @ApiOperation("创建订单")
    @PostMapping("createOrder")
    public ResponseResult createOrder(@RequestBody(required = true) OrderDtos orderDtos){

        UsUser user = UserThread.getUser();
        if(user == null){
            return  ResponseResult.errorResult(AppHttpCodeEnum.TOKEN_EXPIRE);
        }

        //判断有没有库存
        List<CartDtos> goodList = orderDtos.getGoodList();
        List<String> list = new ArrayList<>();
        goodList.forEach(item -> {
//            if(item.getGoodsId().equals(item.getSkuId())){
            if(item.getGoodsId().longValue()==(item.getSkuId().longValue())){
                list.add(REDIS_GOODS_ID + item.getGoodsId() + REDIS_SKU_ID + 0);
            }else {
                list.add(REDIS_GOODS_ID + item.getGoodsId() + REDIS_SKU_ID + item.getSkuId());
            }

        });
//        Long result = stringRedisTemplate.execute(
//                SECKILL_SCRIPT,
//                list
//        );
        System.out.println(list.get(0));
        Long result = stringRedisTemplate.execute(
                SECKILL_SCRIPT,
                list
        );

        int r = result.intValue();
        if(r==1){
            return ResponseResult.errorResult(INSUFFICIENT_INVENTORY);
        }
        orderDtos.setUserId(user.getId());
        RedisIdWorker redisIdWorker = new RedisIdWorker(stringRedisTemplate);
        long orderId = redisIdWorker.nextId(ID_WORK_ORDER);
        orderDtos.setOrderId(orderId);

        // 1.创建CorrelationData
        CorrelationData cd = new CorrelationData(UUID.randomUUID().toString());
        // 2.给Future添加ConfirmCallback
        cd.getFuture().addCallback(new ListenableFutureCallback<CorrelationData.Confirm>() {
            @Override
            public void onFailure(Throwable ex) {
                // 2.1.Future发生异常时的处理逻辑，基本不会触发
                log.error("send message fail", ex);
            }
            @Override
            public void onSuccess(CorrelationData.Confirm result) {
                // 2.2.Future接收到回执的处理逻辑，参数中的result就是回执内容
                if(result.isAck()){ // result.isAck()，boolean类型，true代表ack回执，false 代表 nack回执
                    log.debug("发送消息成功，收到 ack!");
                }else{ // result.getReason()，String类型，返回nack时的异常描述
                    log.error("发送消息失败，收到 nack, reason : " + result.getReason());
                }
            }
        });
        rabbitTemplate.convertAndSend(MQ_EXCHANGE_ORDER,MQ_ROUTINGKEY_ORDER,orderDtos,cd);
        return ResponseResult.okResult(String.valueOf(orderId));
    }



    @ApiOperation("wx创建订单")
    @PostMapping("wxCreateOrder")
    public ResponseResult wxCreateOrder(@RequestBody(required = true) OrderDtos orderDtos){

//        UsUser user = UserThread.getUser();
//        if(user == null){
//            return  ResponseResult.errorResult(AppHttpCodeEnum.TOKEN_EXPIRE);
//        }
//
//        //判断有没有库存
//        List<CartDtos> goodList = orderDtos.getGoodList();
//        List<String> list = new ArrayList<>();
//        goodList.forEach(item -> {
//            list.add(REDIS_GOODS_ID + item.getGoodsId() + REDIS_SKU_ID + item.getSkuId());
//        });
////        Long result = stringRedisTemplate.execute(
////                SECKILL_SCRIPT,
////                list
////        );
//
//        Long result = stringRedisTemplate.execute(
//                SECKILL_SCRIPT,
//                list
//        );
//
//        int r = result.intValue();
//        if(r==1){
//            return ResponseResult.errorResult(INSUFFICIENT_INVENTORY);
//        }
//        orderDtos.setUserId(user.getId());
//        RedisIdWorker redisIdWorker = new RedisIdWorker(stringRedisTemplate);
//        long orderId = redisIdWorker.nextId(ID_WORK_ORDER);
//        orderDtos.setOrderId(orderId);
//
//        // 1.创建CorrelationData
//        CorrelationData cd = new CorrelationData(UUID.randomUUID().toString());
//        // 2.给Future添加ConfirmCallback
//        cd.getFuture().addCallback(new ListenableFutureCallback<CorrelationData.Confirm>() {
//            @Override
//            public void onFailure(Throwable ex) {
//                // 2.1.Future发生异常时的处理逻辑，基本不会触发
//                log.error("send message fail", ex);
//            }
//            @Override
//            public void onSuccess(CorrelationData.Confirm result) {
//                // 2.2.Future接收到回执的处理逻辑，参数中的result就是回执内容
//                if(result.isAck()){ // result.isAck()，boolean类型，true代表ack回执，false 代表 nack回执
//                    log.debug("发送消息成功，收到 ack!");
//                }else{ // result.getReason()，String类型，返回nack时的异常描述
//                    log.error("发送消息失败，收到 nack, reason : " + result.getReason());
//                }
//            }
//        });
//        rabbitTemplate.convertAndSend(MQ_EXCHANGE_ORDER,MQ_ROUTINGKEY_ORDER,orderDtos,cd);
        return ResponseResult.okResult(11111);
    }

}

